﻿// encryptor.c
//
/*
*	AUTHOR：K老叶
*	NAME：加密器
*	LICENSE：Apache License 2.0
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "Dll_encryptor.h"
#pragma warning (disable:4996)
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;

uchar* encryption(uchar* psk, uchar* text)
{
	ushort ps, psk_len;
	ulong i, lenth = strlen(text);
	uchar* string, cache, fair = 0;
	if (lenth == 0 || strlen(psk) == 0)return "";
	string = (uchar*)calloc(lenth * 2 + 1, sizeof(uchar));//分配密文字符串大小
	for (psk_len = 0; psk[psk_len] != 0; psk_len++)
	{
		psk[psk_len] += 81;
		fair ^= psk[psk_len];
	}
	fair /= psk_len;
	for (i = 0, ps = 0; i < (lenth * 2); i++, ps++)
	{
		if (ps >= psk_len) ps = 0;//psk_len位密码循环 
		string[i] = (text[i / 2] + psk[ps]) % 93 + 33;//移位操作,取溢出位
		i++;
		string[i] = (text[(i - 1) / 2] + psk[ps]) / 93 + 33;//补码
		cache = string[i] ^ string[i - 1];
		if (string[i - 1] - fair >= 33)string[i - 1] -= fair;
		if (cache >= 33) string[i] = cache;
	}
	for (i = 0; i < (lenth * 2); i++)
	{
		cache = string[i] ^ fair;
		if (cache >= 33)string[i] = cache;
	}
	string[i] = 0;
	//printf("i:%d\n",i);
	printf("密码长度：%d,密文长度:%d,明文长度%d\n", psk_len, strlen(string), lenth);
	return string;
}

uchar* decryption(uchar* psk, uchar* ciphertext)
{
	ushort ps, psk_len, * dot;
	ulong lenth = strlen(ciphertext), i;
	uchar* c, * text, cache, fair = 0;
	if (lenth == 0 || strlen(psk) == 0)return "";
	c = (uchar*)calloc(lenth / 2 + 1, sizeof(uchar));//分配密文字符串空间
	text = (uchar*)calloc(lenth / 2 + 1, sizeof(uchar));//分配字符串空间
	dot = (ushort*)calloc(lenth / 2, sizeof(ushort));//分配补码数组空间
	for (psk_len = 0; psk[psk_len] != 0; psk_len++)
	{
		psk[psk_len] += 81;
		fair ^= psk[psk_len];
	}
	fair /= psk_len;
	for (i = 0; i < lenth; i++)//第一次脱壳
	{
		cache = ciphertext[i] ^ fair;
		if (cache >= 33)ciphertext[i] = cache;
	}
	//从密文中取出数据
	for (i = 0; i < lenth; i++)
	{
		if (ciphertext[i] + fair >= 33 && i % 2 != 0)ciphertext[i] += fair;
		c[i / 2] = ciphertext[i];
		i++;
		cache = ciphertext[i - 1] ^ ciphertext[i];
		dot[i / 2] = (cache >= 33) ? cache - 33 : ciphertext[i] - 33;
	}

	//解密操作
	for (i = 0, ps = 0; i < lenth / 2; i++, ps++)
	{
		if (ps >= psk_len) ps = 0;//psk_len位密码循环
		text[i] = (dot[i] * 93 + (c[i] - 33)) - psk[ps];//解码公式
	}
	text[i] = 0;
	printf("密码长度：%d,明文长度:%d,密文长度%d\n", psk_len, strlen(c), lenth);
	return text;
}
